/**
 * Copyright FunASR (https://github.com/alibaba-damo-academy/FunASR). All Rights
 * Reserved. MIT License  (https://opensource.org/licenses/MIT)
 */
/* 2022-2023 by zhaoming,mali aihealthx.com */


// 连接; 定义socket连接类对象与语音对象
var wsconnecter = new WebSocketConnectMethod({msgHandle:getJsonMessage,stateHandle:getConnState});
var audioBlob;

// 录音; 定义录音对象,wav格式
var rec = Recorder({
	type:"pcm",
	bitRate:16,
	sampleRate:16000,
	onProcess:recProcess
});

var sampleBuf=new Int16Array();
// 定义按钮响应事件
var btnStart = document.getElementById('btnStart');
btnStart.onclick = record;
var btnStop = document.getElementById('btnStop');
btnStop.onclick = stop;
btnStop.disabled = true;
btnStart.disabled = true;

var sendMsg = document.getElementById('sendMsg');
sendMsg.onclick = sendMessage;

// btnConnect= document.getElementById('btnConnect');
// btnConnect.onclick = start;
var rec_text="";  // for online rec asr result
var offline_text=""; // for offline rec asr result

var isfilemode=false;  // if it is in file mode
var file_ext="";
var file_sample_rate=16000; //for wav file sample rate
var file_data_array;  // array to save file data
 
var totalsend=0;

// 获取下拉框元素
var select = document.getElementById('ketang_num');
// 监听变化
select.addEventListener('change', function() {
  alert('你选择了: ' + this.value);
});

const params = new URLSearchParams(window.location.search);
const session = params.get('session'); // 'paramName'是你想获取的参数名

$(document).ready(function() {
    // getSession();
    // startPlayer();
    getPushUrl(session);
    start();
    
    
})

function getPushUrl(sessionid){
    
    fetch('/session', {
            body: JSON.stringify({
                sessionid: sessionid
            }),
            headers: {
                'Content-Type': 'application/json'
            },
            method: 'POST'
      }).then((response) => {
        // console.log('响应',response)
        if (!response.ok) {
          throw new Error('Network response was not ok ' + response.statusText);
        }
        return response.json(); // 转换为JSON
      }).then((data) => {
          // console.log("session:"+data);
          document.getElementById('sessionid').value = data.sessionid;
          document.getElementById('push_url').value = data.push_url;
          startPlay();
      }).catch((e) => {
        console.log(e);
      });
}

// from https://github.com/xiangyuecn/Recorder/tree/master
var readWavInfo=function(bytes){
	//读取wav文件头，统一成44字节的头
	if(bytes.byteLength<44){
		return null;
	};
	var wavView=bytes;
	var eq=function(p,s){
		for(var i=0;i<s.length;i++){
			if(wavView[p+i]!=s.charCodeAt(i)){
				return false;
			};
		};
		return true;
	};
	
	if(eq(0,"RIFF")&&eq(8,"WAVEfmt ")){
 
		var numCh=wavView[22];
		if(wavView[20]==1 && (numCh==1||numCh==2)){//raw pcm 单或双声道
			var sampleRate=wavView[24]+(wavView[25]<<8)+(wavView[26]<<16)+(wavView[27]<<24);
			var bitRate=wavView[34]+(wavView[35]<<8);
			var heads=[wavView.subarray(0,12)],headSize=12;//head只保留必要的块
			//搜索data块的位置
			var dataPos=0; // 44 或有更多块
			for(var i=12,iL=wavView.length-8;i<iL;){
				if(wavView[i]==100&&wavView[i+1]==97&&wavView[i+2]==116&&wavView[i+3]==97){//eq(i,"data")
					heads.push(wavView.subarray(i,i+8));
					headSize+=8;
					dataPos=i+8;break;
				}
				var i0=i;
				i+=4;
				i+=4+wavView[i]+(wavView[i+1]<<8)+(wavView[i+2]<<16)+(wavView[i+3]<<24);
				if(i0==12){//fmt 
					heads.push(wavView.subarray(i0,i));
					headSize+=i-i0;
				}
			}
			if(dataPos){
				var wavHead=new Uint8Array(headSize);
				for(var i=0,n=0;i<heads.length;i++){
					wavHead.set(heads[i],n);n+=heads[i].length;
				}
				return {
					sampleRate:sampleRate
					,bitRate:bitRate
					,numChannels:numCh
					,wavHead44:wavHead
					,dataPos:dataPos
				};
			};
		};
	};
	return null;
};

function start_file_send()
{
    sampleBuf=new Uint8Array( file_data_array );
    var chunk_size=960; // for asr chunk_size [5, 10, 5]
    while(sampleBuf.length>=chunk_size){
        sendBuf=sampleBuf.slice(0,chunk_size);
        totalsend=totalsend+sampleBuf.length;
        sampleBuf=sampleBuf.slice(chunk_size,sampleBuf.length);
        wsconnecter.wsSend(sendBuf);
    }
    stop();
}

function getAsrMode(){
	var asr_mode = document.getElementById('asr_mode').value;
	console.log("asr mode:    "+asr_mode);
	return asr_mode;
}
		   
function handleWithTimestamp(tmptext,tmptime)
{
	console.log( "tmptext: " + tmptext);
	console.log( "tmptime: " + tmptime);
    if(tmptime==null || tmptime=="undefined" || tmptext.length<=0)
	{
		return tmptext;
	}
	tmptext=tmptext.replace(/。|？|，|、|\?|\.|\ /g, ","); // in case there are a lot of "。"
	var words=tmptext.split(",");  // split to chinese sentence or english words
	var jsontime=JSON.parse(tmptime); //JSON.parse(tmptime.replace(/\]\]\[\[/g, "],[")); // in case there are a lot segments by VAD
	var char_index=0; // index for timestamp
	var text_withtime="";
	for(var i=0;i<words.length;i++)
	{   
	if(words[i]=="undefined"  || words[i].length<=0)
	{
		continue;
	}
    console.log("words===",words[i]);
	console.log( "words: " + words[i]+",time="+jsontime[char_index][0]/1000);
	if (/^[a-zA-Z]+$/.test(words[i]))
	{   // if it is english
		text_withtime=text_withtime+jsontime[char_index][0]/1000+":"+words[i]+"\n";
		char_index=char_index+1;  //for english, timestamp unit is about a word
	}
	else{
        // if it is chinese
		text_withtime=text_withtime+jsontime[char_index][0]/1000+":"+words[i]+"\n";
		char_index=char_index+words[i].length; //for chinese, timestamp unit is about a char
	}
	}
	return text_withtime;
	

}
// 语音识别结果; 对jsonMsg数据解析,将识别结果附加到编辑框中
function getJsonMessage( jsonMsg ) {
	//console.log(jsonMsg);
	console.log( "message: " + JSON.parse(jsonMsg.data)['text'] );
	var rectxt=""+JSON.parse(jsonMsg.data)['text'];
	var asrmodel=JSON.parse(jsonMsg.data)['mode'];
	var is_final=JSON.parse(jsonMsg.data)['is_final'];
	var timestamp=JSON.parse(jsonMsg.data)['timestamp'];
	if(asrmodel=="2pass-offline" || asrmodel=="offline")
	{
		
		offline_text=offline_text+handleWithTimestamp(rectxt,timestamp); //rectxt; //.replace(/ +/g,"");
		rec_text=offline_text;
	}
	else
	{
		rec_text=rec_text+rectxt; //.replace(/ +/g,"");
	}
	var varArea=document.getElementById('chatMessage');
	
	varArea.value=rec_text;
	console.log( "offline_text: " + asrmodel+","+offline_text);
	console.log( "rec_text: " + rec_text);
	if (isfilemode==true && is_final==false){
		console.log("call stop ws!");
		// play_file();
		wsconnecter.wsStop();
        
		// info_div.innerHTML="请点击连接";
		console.log("请点击连接");
		btnStart.disabled = true;
		btnStop.disabled = true;
		// btnConnect.disabled=false;
	}
 
}

// 连接状态响应
function getConnState( connState ) {
	if ( connState === 0 ) { //on open
 
		// info_div.innerHTML='连接成功!请点击开始';
		console.log("连接成功!请点击开始");
		if (isfilemode==true){
			// info_div.innerHTML='请耐心等待,大文件等待时间更长';
			console.log("请耐心等待,大文件等待时间更长");
			start_file_send();
		}
		else
		{
			btnStart.disabled = false;
			btnStop.disabled = true;
			// btnConnect.disabled=true;
		}
	} else if ( connState === 1 ) {
		//stop();
	} else if ( connState === 2 ) {
		stop();
		console.log( 'connecttion error' );
		 
		alert("连接地址"+document.getElementById('wssip').value+"失败,请检查asr地址和端口。或试试界面上手动授权，再连接。");
		btnStart.disabled = true;
		btnStop.disabled = true;
		// btnConnect.disabled=false;
 
		// info_div.innerHTML='请点击连接';
		console.log("请点击连接");
	}
}

var is_open = false;
var num_open = 0;
function record()
{
	if(!is_open){
		rec.open( function(){
			rec.start();
			is_open = true;
			console.log("record开始1");
			// btnStart.disabled = true;
			btnStart.innerText="关闭语音"
			btnStop.disabled = false;
			// btnConnect.disabled=true;
		});
	}else{
		if(num_open%2==0){
			btnStart.innerText="开启语音"
			isRec = false;
			rec_text = "";
		}else{
			btnStart.innerText="关闭语音"
			isRec = true;
		}
		num_open++;
	}
 
}

 

// 识别启动、停止、清空操作
function start() {
	
	// 清除显示
	// clear();
	//控件状态更新
 	console.log("isfilemode:   "+isfilemode);
	//启动连接
	var ret=wsconnecter.wsStart();
	// 1 is ok, 0 is error
	if(ret==1){
		// info_div.innerHTML="正在连接asr服务器，请等待...";
		console.log("正在连接asr服务器，请等待...");
		isRec = true;
		btnStart.disabled = true;
		btnStop.disabled = true;
		// btnConnect.disabled=true;
 
        return 1;
	}
	else
	{
		// info_div.innerHTML="请点击开始";
		console.log("请点击开始");
		btnStart.disabled = true;
		btnStop.disabled = true;
		// btnConnect.disabled=false;
 
		return 0;
	}
}

 
function stop() {
		var chunk_size = new Array( 5, 10, 5 );
		var request = {
			"chunk_size": chunk_size,
			"wav_name":  "h5",
			"is_speaking":  false,
			"chunk_interval":10,
			"mode":getAsrMode(),
		};
		console.log(request);
		if(sampleBuf.length>0){
			wsconnecter.wsSend(sampleBuf);
			console.log("sampleBuf.length"+sampleBuf.length);
			sampleBuf=new Int16Array();
		}
	   wsconnecter.wsSend( JSON.stringify(request) );
 
	// 控件状态更新
	
	// isRec = false;
    // info_div.innerHTML="发送完数据,请等候,正在识别...";
	console.log("发送完数据,请等候,正在识别...");
   if(isfilemode==false){
	    btnStop.disabled = true;
		btnStart.disabled = false;
		// btnConnect.disabled=true;
		//wait 3s for asr result
	//   setTimeout(function(){
	// 		console.log("call stop ws!");
	// 		wsconnecter.wsStop();
	// 		// btnConnect.disabled=false;
	// 		// info_div.innerHTML="请点击连接";
	// 		console.log("请点击连接");
	// 	}, 3000 );
	
		rec.stop(function(blob,duration){
			
			console.log(blob);
			var audioBlob = Recorder.pcm2wav(data = {sampleRate:16000, bitRate:16, blob:blob},
			function(theblob,duration){
					console.log(theblob);
			// var audio_record = document.getElementById('audio_record');
			// audio_record.src =  (window.URL||webkitURL).createObjectURL(theblob); 
			// audio_record.controls=true;
			//audio_record.play(); 
				
			}   ,function(msg){
				console.log(msg);
			}
			);
	
		},function(errMsg){
			console.log("errMsg: " + errMsg);
			
		});
   }
    // 停止连接

}

// function clear() {
 
//     var varArea=document.getElementById('chatMessage');
 
// 	varArea.value="";
//     rec_text="";
// 	offline_text="";
 
// }

 
function recProcess( buffer, powerLevel, bufferDuration, bufferSampleRate,newBufferIdx,asyncEnd ) {
	if ( isRec === true ) {
		var data_48k = buffer[buffer.length-1];  
 
		var  array_48k = new Array(data_48k);
		var data_16k=Recorder.SampleData(array_48k,bufferSampleRate,16000).data;
 
		sampleBuf = Int16Array.from([...sampleBuf, ...data_16k]);
		var chunk_size=960; // for asr chunk_size [5, 10, 5]
		// info_div.innerHTML=""+bufferDuration/1000+"s";
		console.log(""+bufferDuration/1000+"s");
		while(sampleBuf.length>=chunk_size){
		    sendBuf=sampleBuf.slice(0,chunk_size);
			sampleBuf=sampleBuf.slice(chunk_size,sampleBuf.length);
			wsconnecter.wsSend(sendBuf);
			
			
		 
		}
		
 
		
	}
}

////////////////////////////////////////////////////////////////////////////////////
///////////////////////// srs推流
////////////////////////////////////////////////////////////////////////////////////

var sdk = null; // Global handler to do cleanup when republishing.
  var is_sdk_player = false;
  var is_pause = false;
  $(document).ready(function() {

  })

  function playVideo() {
      const video = document.getElementById('videoPlayer');
      // $('#videoPlayer').prop('srcObject', "teacher1.mp4");
      // video.src = "teacher1.mp4";
      video.play();
  }

  var currentTimeVedio = 0;
  function pauseVideo() {
      const video = document.getElementById('videoPlayer');
      video.pause();
      currentTimeVedio = video.currentTime
      console.log("currentTimeVedio:"+currentTimeVedio)
      is_pause = true;
  }

  function switchVedio(path){
    const video = document.getElementById('videoPlayer');
    video.src = path;
	video.currentTime = currentTimeVedio;
	video.srcObject = null;
	// var source = video.querySelector('source');
	// source.getAttribute('src') = path;
	// var src = source.getAttribute('src')
	// console.log('视频地址:', src); // 在控制台打印视频地址
    video.play();
  }

  function handQuestion(){
    // 需要一个过度视频，学生你好，你需要什么帮助呢
    // switchVedio("teacher2.mp4")
    if(!is_sdk_player){
	  pauseVideo();
      // startPlay();
      disOrHidVedio();
      // handStartPlay();
      handStartPlay();
      // sendHandMessage();
	  is_sdk_player=true;
    }
  }
  function kejianVideo(){
    if(is_sdk_player){
        fetch('/startplay', {
            body: JSON.stringify({
                // text: message,
                // type: 'echo',
                kt_num: '1-1',
                // interrupt: true,
                sessionid:parseInt(document.getElementById('sessionid').value),
            }),
            headers: {
                'Content-Type': 'application/json'
            },
            method: 'POST'
      }).then(response=>{
        console.log('响应',response)
        if (!response.ok) {
          throw new Error('Network response was not ok ' + response.statusText);
        }
        return response.json(); // 转换为JSON
      }).then(data => {
        console.log("AI:"+data.data); // 处理JSON数据

      }).catch(error => {
        // console.error('There has been a problem with your fetch operation:', error); // 捕获错误
      });


          
    }
  }

  function disOrHidVedio(){
      const video = document.getElementById('videoPlayer');
      video.style.display = 'none';
      const video2 = document.getElementById('videoPlayer2');
      video2.style.display = 'inline'; // 或者 'block' 或其他适合的显示属性
  }
  function disOrHidVedio2(){
      const video = document.getElementById('videoPlayer2');
      video.style.display = 'none';
      const video2 = document.getElementById('videoPlayer');
      video2.style.display = 'inline'; // 或者 'block' 或其他适合的显示属性
  }
  function continueVideo() {
    if(is_pause){
      const video = document.getElementById('videoPlayer');
      video.currentTime = currentTimeVedio;
      console.log("continueVideo.src="+video.src);
	  // 获取第一个source元素的src属性
	  var source = video.querySelector('source');
	  var src = source.getAttribute('src');
	  console.log('视频地址:', src); // 在控制台打印视频地址
	  
      console.log("continueVideo.srcObject="+video.srcObject);
      // video.src = "teacher1.mp4";
      // $('#videoPlayer').prop('srcObject', "teacher1.mp4");
      disOrHidVedio2();
	  if(is_sdk_player){
		 switchVedio("teacher1.mp4");
		//  source.setAttribute('src',"teacher2.mp4");
		//  sdk.close();
		//  $('#videoPlayer').prop('srcObject', sdk.stream);
	  }else{
		video.play();
	  }
      
      is_pause=false;
      is_sdk_player=false;
      // sdk.close();
    }
  }

  function stopVideo() {
      const video = document.getElementById('videoPlayer');
      video.pause();
      video.currentTime = 0;
  }

  function isEmptyMessage(value) {
    return value === '' || value === null || value === undefined;
  }

  function sendMessage() {
	  
      const message = document.getElementById('chatMessage').value;
	  if(isEmptyMessage(message)){
		alert("不能发送空消息");
		return;
	  }
	  //关闭语音
	  btnStart.innerText="开启语音"
	  isRec = false;
	  rec_text = "";
      
      const messages = document.getElementById('chatMessages');
      const newMessage = document.createElement('div');
	  rec_text = "";
      newMessage.textContent = "YOU:"+message;
      messages.appendChild(newMessage);
      document.getElementById('chatMessage').value = ''; // 清空输入框
      console.log('Sending: ' + message);
      fetch('/human', {
            body: JSON.stringify({
                text: message,
                type: 'echo',
                interrupt: true,
                sessionid:parseInt(document.getElementById('sessionid').value),
            }),
            headers: {
                'Content-Type': 'application/json'
            },
            method: 'POST'
      }).then(response=>{
        console.log('响应',response)
        if (!response.ok) {
          throw new Error('Network response was not ok ' + response.statusText);
        }
        return response.json(); // 转换为JSON
      }).then(data => {
        console.log("AI:"+data.data); // 处理JSON数据
        
        // messages.appendChild(data.data);
        const newMessage2 = document.createElement('div');
        newMessage2.textContent = "AI:  "+data.data;
        messages.appendChild(newMessage2);
        if(!is_sdk_player){
          pauseVideo();
          disOrHidVedio();
          startPlay();
          is_sdk_player=true;
        }

      }).catch(error => {
        // console.error('There has been a problem with your fetch operation:', error); // 捕获错误
      });

  }
  
  function startPlay(){
    // Close PC when user replay.
    if (sdk) {
        sdk.close();
    }
    sdk = new SrsRtcWhipWhepAsync();
    // User should set the stream when publish is done, @see https://webrtc.org/getting-started/media-devices
    // However SRS SDK provides a consist API like https://webrtc.org/getting-started/remote-streams
    $('#videoPlayer2').prop('srcObject', sdk.stream);
    // const video = document.getElementById('videoPlayer');  
    // video.play();
    // Optional callback, SDK will add track to stream.
    // sdk.ontrack = function (event) { console.log('Got track', event); sdk.stream.addTrack(event.track); };
    var host = window.location.hostname;
    var sub_url = document.getElementById('push_url').value;
    console.log("----sub_url------------"+sub_url);
    // // For example: webrtc://r.ossrs.net/live/livestream
    // var url = "http://"+host+":1985/rtc/v1/whep/?app=live&stream=livestream"
    var url = "http://"+host+":1985/rtc/v1/whep/?app=live&"+sub_url
    sdk.play(url).then(function(session){
        console.log("session:"+session.sessionid)
        //$('#sessionid').html(session.sessionid);
        //$('#simulator-drop').attr('href', session.simulator + '?drop=1&username=' + session.sessionid);
    }).catch(function (reason) {
        sdk.close();
        // $('#videoPlayer').hide();
        console.error(reason);
    });

  }

  function handStartPlay(){
    // Close PC when user replay.
    if (sdk) {
        sdk.close();
    }
    sdk = new SrsRtcWhipWhepAsync();
    // User should set the stream when publish is done, @see https://webrtc.org/getting-started/media-devices
    // However SRS SDK provides a consist API like https://webrtc.org/getting-started/remote-streams
    $('#videoPlayer2').prop('srcObject', sdk.stream);
    // Optional callback, SDK will add track to stream.
    // sdk.ontrack = function (event) { console.log('Got track', event); sdk.stream.addTrack(event.track); };
    var host = window.location.hostname;
    var sub_url = document.getElementById('push_url').value;
    console.log("----sub_url------------"+sub_url);
    // // For example: webrtc://r.ossrs.net/live/livestream
    // var url = "http://"+host+":1985/rtc/v1/whep/?app=live&stream=livestream"
    var url = "http://"+host+":1985/rtc/v1/whep/?app=live&"+sub_url
    sdk.play(url).then(function(session){
        
        // setTimeout("sendHandMessage()",5000 );
        console.log("---handStartPlay-----------session:"+session.sessionid);
        
        //$('#sessionid').html(session.sessionid);
        //$('#simulator-drop').attr('href', session.simulator + '?drop=1&username=' + session.sessionid);
    }).catch(function (reason) {
        sdk.close();
        // $('#videoPlayer').hide();
        console.error(reason);
    });
    sendHandMessage();
  }

  function sendHandMessage() {
	  //关闭语音
	  btnStart.innerText="开启语音"
	  isRec = false;
	  rec_text = "";

      fetch('/human', {
            body: JSON.stringify({
                text: '你好同学,请问你有什么问题，我可以帮助你的吗',
                type: 'echo',
                // interrupt: true,
                sessionid:parseInt(document.getElementById('sessionid').value),
            }),
            headers: {
                'Content-Type': 'application/json'
            },
            method: 'POST'
      }).then(response=>{
        console.log('响应',response)
        if (!response.ok) {
          throw new Error('Network response was not ok ' + response.statusText);
        }
        return response.json(); // 转换为JSON
      }).then(data => {
        console.log("hand:"+data.data); // 处理JSON数据
      }).catch(error => {
        // console.error('There has been a problem with your fetch operation:', error); // 捕获错误
      });

  }
